//
//  AudioRecorder.swift
//  WaveformDemo
//
//  Created by liyahao on 2025/4/10.
//

import UIKit
import AVFoundation

// 音频录制管理器
class AudioRecorder: NSObject, ObservableObject {
    @Published var audioSamples: [CGFloat] = []
    @Published var duration: TimeInterval = 0.0
    @Published var isRecording: Bool = false
    @Published var placeName: String = ""
    @Published var asr: String?
    @Published var audioName: String = "新录音"
    
    // 是否
    let sampleRate: TimeInterval = 0.05
    var timer: Timer?
    
    private var lat: String?
    private var lng: String?
    private var audioFilePath: URL?
    private var audioRecorder: AVAudioRecorder?
    private var audioPlayer: AVAudioPlayer?
    private let sampleDataQueue = DispatchQueue(label: "com.audiorecorder.sampleDataQueue")
    
    // 开始录音
    func startRecording(audioFilePath: URL) {
        // 开始定位
        if lat == nil { self.setupLocationCallbacks() }
        
        // 请求麦克风权限
        let audioSession = AVAudioSession.sharedInstance()
        
        do {
            try audioSession.setCategory(.playAndRecord, mode: .default)
            try audioSession.setActive(true)
            
            // 录音设置
            let settings = [
                AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                AVSampleRateKey: 44100,
                AVNumberOfChannelsKey: 1,
                AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
            ]
            
            // 初始化录音器
            audioRecorder = try AVAudioRecorder(url: audioFilePath, settings: settings)
            audioRecorder?.delegate = self
            audioRecorder?.isMeteringEnabled = true
            audioRecorder?.prepareToRecord()
            audioRecorder?.record()
            self.audioFilePath = audioFilePath
            
            // 开始监听音频电平
            startMonitoring()
        } catch {
            self.isRecording = false
            self.audioFilePath = nil
            print("录音设置失败: \(error.localizedDescription)")
        }
    }
    
    // 停止录音
    func stopRecording() {
        audioRecorder?.stop()
        stopMonitoring()
        
        if let audio = self.audioFilePath {
            let files = AudioFiles(
                id: 0,
                name: audioName,
                duration: Int(duration),
                path: audio.lastPathComponent,
                group: "未分组",
                asr: self.asr,
                tsp: Date.tspString,
                location: self.placeName,
                lat: self.lat,
                lng: self.lat)
            SQLManager.share.local.insert(model: files)
        } else {
            print("录音失败")
        }
    }
    
    // 暂停录音
    func pauseRecording() {
        isRecording = false
        audioRecorder?.pause()
    }
    
    // 恢复录音
    func reStartRecording() {
        isRecording = true
        audioRecorder?.record()
    }
    
    private func startMonitoring() {
        isRecording = true
        timer = Timer.scheduledTimer(withTimeInterval: sampleRate, repeats: true) { [weak self] _ in
            self?.updateMeters()
        }
    }
    
    private func stopMonitoring() {
        isRecording = false
        timer?.invalidate()
        timer = nil
    }
    
    private func updateMeters() {
        guard let recorder = audioRecorder, isRecording else {
            return
        }
        
        duration += sampleRate
        
        recorder.updateMeters()
        
        // 从录音器获取电平数据
        let level = recorder.averagePower(forChannel: 0)
        let normalizedValue = normalizeSoundLevel(level: level)
        
        // 在主线程更新UI数据
        DispatchQueue.main.async {
            self.audioSamples.append(CGFloat(normalizedValue))
        }
    }
    
    // 将dB电平转换为0-1之间的值
    private func normalizeSoundLevel(level: Float) -> Float {
        // 输入电平范围约为-160 到 0 dB
        let minDb: Float = -50.0
        
        if level < minDb {
            return 0.05 // 静音时仍然显示一点点波形
        } else {
            // 将 -50-0 dB 范围映射到 0.05-1.0
            return 0.05 + 0.95 * (level - minDb) / (-minDb)
        }
    }
}

extension AudioRecorder: AVAudioRecorderDelegate {
    @objc func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool){
//        if let url = recordingURL {
//            self.finishRecording?(url)
//        }
    }
    
    @objc func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {
        
    }
    
    @objc func audioRecorderBeginInterruption(_ recorder: AVAudioRecorder){
        
    }
    
    @objc func audioRecorderEndInterruption(_ recorder: AVAudioRecorder, withOptions flags: Int){
        
    }
}

extension AudioRecorder {
    private func setupLocationCallbacks() {
        // 设置位置更新回调
        LocationManager.shared.didUpdateLocation = { [weak self] location in
            DispatchQueue.main.async {
                print("ViewController: Received location update: \(location.coordinate.latitude), \(location.coordinate.longitude)")
                self?.lat = "\(location.coordinate.latitude)"
                self?.lng = "\(location.coordinate.longitude)"
            }
        }
        
        LocationManager.shared.didUpdatePlaceName = { [weak self] placeName in
            DispatchQueue.main.async {
                print("ViewController: Received place name: \(placeName)")
                self?.placeName = placeName
            }
        }
        
        let status = LocationManager.shared.authorizationStatus
        if status == .notDetermined {
            // 如果从未请求过权限，发起请求
            LocationManager.shared.requestWhenInUseAuthorization()
        } else if status == .authorizedWhenInUse || status == .authorizedAlways {
            // 如果已有权限，直接开始获取位置
            LocationManager.shared.startUpdatingLocation()
        } else if status == .denied || status == .restricted {
            // 如果权限被拒绝，提示用户
            print("Permission previously denied or restricted.")
        }
    }
}
